package ca.tatham.scheduler;

import java.util.Collection;
import java.util.LinkedList;
import java.util.Stack;

public abstract class AbstractTask implements Task {
	private final String m_name;
	private final int m_originalPriority;
	private final Collection<Object> m_resources;
	private final Stack<Integer> m_priorities;

	private int m_priority;
	private boolean m_blocked = false;

	public AbstractTask(String name, int priority) {
		m_name = name;
		m_originalPriority = priority;
		m_priorities = new Stack<Integer>();
		m_priority = priority;
		m_resources = new LinkedList<Object>();
	}

	// public final synchronized void block() {
	// m_blocked = true;
	// System.out.println("Blocking " + getName());
	// }
	//
	// public final synchronized void release() {
	// m_blocked = false;
	// notify();
	// }

	protected final synchronized void checkBlock() {
		if (m_blocked) {
			try {
				wait();
			} catch (InterruptedException e) {
				checkBlock();
			}
		}
	}

	protected void addResource(Object object) {
		m_resources.add(object);
	}

	public final Collection<Object> getUsedResources() {
		return m_resources;
	}

	public final String getName() {
		return m_name;
	}

	public final int getOriginalPriority() {
		return m_originalPriority;
	}

	public final int getPriority() {
		return m_priority;
	}

	public final void promote(int priority) {
		m_priorities.push(m_priority);
		m_priority = priority;
	}

	public final boolean demote() {
		if (m_priorities.size() > 0) {
			m_priority = m_priorities.pop();
			return true;
		}
		m_priority = m_originalPriority;
		return false;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof Task) {
			Task that = (Task) obj;
			return that.getOriginalPriority() == this.getOriginalPriority()
					&& that.getName().equals(this.getName());
		}
		return false;
	}

	@Override
	public String toString() {
		return getName();
	}

}
